package com.sadhoc.sockets;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

public class UDPSender implements Runnable {
	
	private DatagramSocket socket = null;
	private Queue<DatagramPacket> queue = null;
	boolean running = true;
	
	/*
	 * Constructor
	 */
	public UDPSender() throws SocketException {
		
		socket = new DatagramSocket();
		queue = new ConcurrentLinkedQueue<DatagramPacket>();
	}
	
	/*
	 * Writes the HDPacket as a byte array in a UDP Datagram.
	 * We will need to determine maximum byte restrictions to avoid fragmentation
	 * and loss of fragmented packets. The limitation will need to be applied
	 * to the HDPacket class as well. 
	 */
	public void send(String destIP, int destPort, byte[] data) throws IOException {
		
		DatagramPacket p = new DatagramPacket(data, data.length, InetAddress.getByName(destIP), destPort);
		queue.add(p);
		synchronized (queue) {
			queue.notify();
		}
				
	}

	/*
	 * Sends UDP messages that are in the queue.
	 */
	public void run() {
		
		while (running) {
			try {
				
				synchronized(queue) {
					while (queue.isEmpty()) {
						queue.wait();
					}
				}

				socket.send(queue.poll());
				
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	/*
	 * Stops the thread
	 */
	public void stop() {
		
		running = false;
		
	}
}
